#include "Common.hpp"

// ./tcpclient server_ip server_port
int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        LOG(LogLevel::FATAL) << "Usage: " << argv[0] << " server_ip server_port";
        exit(USAGE_ERR);
    }

    std::string ip = argv[1];
    uint16_t port = std::stoi(argv[2]);
    InetAddr addr(port, ip);

    // 1.创建套接字
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        LOG(LogLevel::FATAL) << "socket error";
        exit(SOCKET_ERR);
    }
    LOG(LogLevel::INFO) << "socket success, sockfd: " << sockfd;

    // 2.绑定，不需要显式绑定，在建立连接时会自动bind
    // 2.建立连接
    socklen_t len = sizeof(struct sockaddr_in);
    int ret = connect(sockfd, CONV(addr.Peer()), len);
    if (ret < 0)
    {
        LOG(LogLevel::FATAL) << "connect error";
        exit(CONNECT_ERR);
    }
    LOG(LogLevel::INFO) << "connect success, sockfd: " << sockfd;

    while (true)
    {
        std::cout << "Please Enter# ";
        std::string line;
        std::getline(std::cin, line);
        ssize_t n = write(sockfd, line.c_str(), line.size());
        if (n < 0)
        {
            LOG(LogLevel::WARNING) << "write error";
            continue;
        }

        char buff[512];
        n = read(sockfd, buff, sizeof(buff) - 1);
        if (n < 0)
        {
            LOG(LogLevel::WARNING) << "read error";
            continue;
        }
        else if (n == 0)
        {
            LOG(LogLevel::INFO) << "server write exit, so client read exit";
            break;
        }
        else
        {
            buff[n] = 0;
            LOG(LogLevel::INFO) << buff;
        }
    }

    return 0;
}